// 递归
// 本质是：解决主问题时，发现相同子问题，解决主问题和子问题的方法相同
// 心理暗示：宏观看待递归问题，把递归函数当成黑盒，相信这个黑盒一定能完成任务
// 技巧：
//      找到重复子问题 -> 设计函数头
//      子问题是如何解决的 -> 函数体的书写
//      注意递归函数的出口 -> 关注问题不能分割的情况
// 拓展：如果一个题目可以用决策树画出来，那么也可以通过递归解决

// 例题 1：
// 在经典汉诺塔问题中，有 3 根柱子及 N 个不同大小的穿孔圆盘，盘子可以滑入任意一根柱子。
// 一开始，所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
//        (1) 每次只能移动一个盘子;
//        (2) 盘子只能从柱子顶端滑出移到下一根柱子;
//        (3) 盘子只能叠在比它大的盘子上。
//
//        请编写程序，用栈将所有盘子从第一根柱子移到最后一根柱子。
//
//        你需要原地修改栈。
//
//        示例 1：
//
//        输入：A = [2, 1, 0], B = [], C = []
//        输出：C = [2, 1, 0]
//        示例 2：
//
//        输入：A = [1, 0], B = [], C = []
//        输出：C = [1, 0]
//        提示：
//
//        A 中盘子的数目不大于 14 个。

// 解题思路：
// 假设有 n 个盘子，A 柱先移动  n - 1 个盘子到 B 柱
// A 柱再移动 1 个盘子到 C 柱
// B 柱再移动 n - 1 个盘子到 C柱
// 如果只有 1 个盘子，那么直接从 A 柱移到 C 柱

import java.util.List;

public class Hanota {
    public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
        int n = A.size();
        move(A, B, C, n);
    }
    public void move(List<Integer> A, List<Integer> B, List<Integer> C, int n){
        if(n == 1){
            int a = A.remove(A.size() - 1);
            C.add(a);
        }else{
            move(A, C, B, n - 1);
            move(A, B, C, 1);
            move(B, A, C, n - 1);
        }
    }
}
